package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 刘付磊
 * @date 2021/11/17 0017
 */
@Service
public class MovementsService {

    @DubboReference
    private MovementApi movementApi;

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void movements(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1.判断发布动态的内容是否存在
        //StringUtils.isEmty
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2.获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3.将文件内容上传到阿里云oss获取请求地址
        List<String> list = new ArrayList();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(
                    multipartFile.getOriginalFilename(),
                    multipartFile.getInputStream());
            list.add(upload);
        }
        //4.将数据封装到movement对象
        movement.setUserId(userId);
        movement.setMedias(list);
        //5.调用api完成发布动态
        movementApi.publish(movement);
    }

    /*查询个人动动态*/
    public PageResult findAll(Long userId, Integer page, Integer pagesize) {
        UserInfo byId = userInfoApi.findById(userId);
        //1.根据用户id，调用aip查询个人动态内容（PageResult -- movement）
        PageResult pr = movementApi.findAll(userId, page, pagesize);
        //2.获取pageResult中的item列表对象
        List<Movement> list = (List<Movement>) pr.getItems();
        //3.判断是否为空
        if (list == null) {
            return pr;
        }
        //4.循环列表
        List<MovementsVo> volist = new ArrayList<>();
        for (Movement movement : list) {
            //5.一个movement构建一个vo对象
            MovementsVo vo = MovementsVo.init(byId, movement);
            volist.add(vo);
        }
        pr.setItems(volist);
        return pr;
    }

    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //1.获取当前用户的id
        Long userId = UserHolder.getUserId();
        //2.根据api获取当前用户好友的动态.
        List<Movement> list = movementApi.findFriendMovements(page, pagesize, userId);
        //3.判断是否为空
        return getPageResult(page, pagesize, list);
    }

    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> list) {
        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //4.提取发布人的id
        List<Long> values = CollUtil.getFieldValues(list, "userId", Long.class);
        //5.根据id获取好友用户的信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(values, null);
        //6.封装vo
        List<MovementsVo> items = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = map.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                //修复点赞状态的bug，判断hashkey是否存在
                String key = Constants.MOVEMENTS_INTERACT_KEY+movement.getId().toHexString();
                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
                if(redisTemplate.opsForHash().hasKey(key,hashKey)){
                    vo.setHasLiked(1);
                }
                items.add(vo);
            }
        }
        //7.构造PageResult并返回
        PageResult pr = new PageResult(page, pagesize, 0, items);
        return pr;
    }

    //查询推荐动态
    public PageResult recommend(Integer page, Integer pagesize) {
        //1.从redis中获取数据
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        //2.判断数据是否存在
        String s = redisTemplate.opsForValue().get(redisKey);
        List<Movement> list = Collections.EMPTY_LIST;
        if (StringUtils.isEmpty(s)) {
            //3.如果不存在，调用api随机构造10条动态数据
            list = movementApi.randomMovements(pagesize);
        } else {
            //4.如果存在处理pid数据
            String[] split = s.split(",");
            //判断当前页起始条数是否小于数组总数
            if ((page - 1) * pagesize < split.length) {
                List<Long> collect = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e))
                        .collect(Collectors.toList());
                //5.调用api根据pid数组查询动态数据
                list = movementApi.findMovementsByPids(collect);
            }
        }
        //6.调用公共方法 构造返回值
        return getPageResult(page, pagesize, list);
    }

    public MovementsVo findById(String movementId) {
        //1.调用api根据id查询动态
        Movement movement = movementApi.findById(movementId);
        //2.转化为vo对象
        if (movement != null) {
            UserInfo byId = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(byId, movement);
        } else {
            return null;
        }
    }
    @DubboReference
    private VisitorsApi  visitorsApi;
        //首页访客列表
    public List<VisitorsVo> queryVisitorsList() {
        //1.查询访问时间
        String key = Constants.VISITORS_USER;
        String hashKey = String.valueOf(UserHolder.getUserId());
        String value = (String) redisTemplate.opsForHash().get(key, hashKey);
        Long date = StringUtils.isEmpty(value) ? null : Long.valueOf(value);
        //2.调用api查询数据列表
        List<Visitors> list= visitorsApi.queryVisitorsList(UserHolder.getUserId(),date);
        if(CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }
        //2.1提取用户id
        List<Long> visitorUserId = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        //2.2查看用户详细
        Map<Long, UserInfo> map = userInfoApi.findByIds(visitorUserId, null);
        //3.构造vo
        List<VisitorsVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            if(ObjectUtil.isNotEmpty(userInfo)){
                VisitorsVo vo = VisitorsVo.init(userInfo, visitors);
                vos.add(vo);
            }
        }
        return vos;
    }
}
